﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

using WpfElevator.GlobalConstant;
using WpfElevator.ControlPart;
using AbstractFramework.Constant;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
namespace WpfElevator.RequisitionPart
{
    class Requisition
    {
        public Event eve;
        private RequisitionType m_requisitionType;//请求类型
        private int m_ID;//电梯编号
        private int m_requisitionFloor;//目的楼层
        private int m_updown;//外部按钮请求向上还是向下
        private int m_Floor;//外部按钮所在的楼层

        public int requisitionFloor
        {
            get
            {
                return m_requisitionFloor;
            }
            set
            {
                m_requisitionFloor = value;
            }
        }
        public int updown
        {
            get
            {
                return m_updown;
            }
            set
            {
                m_updown = value;
            }
        }
        public int floor
        {
            get
            {
                return m_Floor;
            }
            set
            {
                m_Floor = value;
            }
        }
        public int ID
        {
            get
            {
                return m_ID;
            }
            set
            {
                m_ID = value;
            }
        }
        public RequisitionType requisitionType
        {
            get
            {
                return m_requisitionType;
            }
            set
            {
                m_requisitionType = value;
            }
        }
        public void createNewRequisition()
        {
        }
    }

    class ButtonRequisition : Requisition
    {
        public ButtonRequisition()
        {
        }//无参构造器
        public ButtonRequisition(RequisitionType reqType, int floor, int id)
        {
            if (reqType == RequisitionType.insideReq)//内部按钮产生请求
            {
                requisitionType = reqType;
                requisitionFloor = floor;
                ID = id;
            }
            else if (reqType == RequisitionType.outsideReq)//外部按钮产生请求，参数包括请求楼层和上下行标识
            {
                requisitionType = reqType;
                updown = id;//0表示向下，1表示向上
                this.floor = floor;
            }
            else
            {
                Console.WriteLine("输入有误");
            }
        }
        public ButtonRequisition(RequisitionType reqType)//火灾请求
        {
            if (reqType == RequisitionType.fireReq)
            {
                requisitionType = reqType;
            }
        }
        public void createNewRequisition()
        {
            if (requisitionType == RequisitionType.outsideReq)//外部请求
            {
                eve = new Event(EventType.outsideEvent, floor, updown);
            }
            else if (requisitionType == RequisitionType.insideReq)//内部请求
            {
                eve = new Event(EventType.insideEvent, requisitionFloor, ID);
            }
            else if (requisitionType == RequisitionType.fireReq)//火警
            {
                eve = new Event(EventType.fireEvent);
            }
            GConstant.controller.addEvent(eve);
        }
    }

    class FileRequisition : Requisition
    {
        public int MAXELENUM;//最大电梯数目
        public int MAXFLOOR;//最高楼层
        public string filePath;
        private int sleepTime = 0;
        private System.Windows.Threading.Dispatcher dispatcher;
        public FileRequisition(int MAXFLOOR, int MAXELENUM, string filePath, System.Windows.Threading.Dispatcher dispatcher)
        {
            this.MAXELENUM = MAXELENUM;
            this.MAXFLOOR = MAXFLOOR;
            this.filePath = filePath;
            this.dispatcher = dispatcher;
        }
        public void createNewRequisition()
        {
            List<string[]> list = new List<string[]>();
            using (TextReader txt = new StreamReader(filePath))
            {
                string line;
                while ((line = txt.ReadLine()) != null)
                {
                    list.Add(Regex.Split(line.Trim(), "\\s+"));
                }
            }

            // txt文件中的数组以字符串形式存在array中
            string[][] array = list.ToArray();

            // 以下对字符串数组 array 进行操作
            //Console.WriteLine(array.Length);
            for (int i = 0; i < array.Length; i++)
            {
                if (array[i][0].Equals("0"))
                {
                    //赋值，创建event对象，然后加入到队列中去
                    int m = Int16.Parse(array[i][1]);//m存储着外部按钮所在的楼层
                    int j = Int16.Parse(array[i][2]);//j存着向上还是向下
                    if (m <= MAXFLOOR - 1 && m >= 0 && j >= 0 && j <= 1)
                    {
                        eve = new Event(EventType.outsideEvent, m, j);
                        //过指定时刻产生请求
                        sleepTime = Int16.Parse(array[i][3]);
                        Thread.Sleep(sleepTime * 1000);
                       // GConstant.controller.addEvent(eve);
                       subThreadAddEvent(eve);
                    }
                    else continue;
                }
                else if (array[i][0].Equals("1"))
                {
                    //赋值，创建event对象，然后加入到队列中去
                    int m = Int16.Parse(array[i][1]);//i存储着内部按钮请求的楼层
                    int j = Int16.Parse(array[i][2]);//j存着内部按钮所在的电梯ID
                    if (j <= MAXELENUM - 1 && j >= 0 && m >= 0 && m <= MAXFLOOR - 1)
                    {
                        eve = new Event(EventType.insideEvent, m, j);
                        //过指定时刻产生请求
                        sleepTime = Int16.Parse(array[i][3]);
                        Thread.Sleep(sleepTime * 1000);
                        //GConstant.controller.addEvent(eve);
                        subThreadAddEvent(eve);
                    }
                    else continue;
                }
                else if (array[i][0].Equals("2"))//文件的火警请求包含两个值：第一个为“2”，第二个为请求产生的等待时间
                {
                    //创建event对象，加入队列
                    eve = new Event(EventType.fireEvent);
                    //过指定时刻产生请求
                    sleepTime = Int16.Parse(array[i][1]);
                    Thread.Sleep(sleepTime * 1000);
                   //GConstant.controller.addEvent(eve);
                    subThreadAddEvent(eve);
                }
                else
                    continue;
            }
        }
        public delegate void addEvent(Event even);
        public void addElevatorEvent(Event even)
        {
            GConstant.controller.addEvent(even);
        }
        public void subThreadAddEvent(Event even)
        {
            this.dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new addEvent(addElevatorEvent), even);
        }
    }

    //class RandomRequisition : Requisition
    //{
    //    public int MAXELENUM;//最大电梯数目
    //    public int MAXFLOOR;//最高楼层

    //    public RandomRequisition(int MAXFLOOR, int MAXELENUM)
    //    {
    //        this.MAXELENUM = MAXELENUM;
    //        this.MAXFLOOR = MAXFLOOR;
    //    }
    //    public void createNewRequisition()
    //    {
    //        Random ra = new Random();
            
    //        for (int i = 0; i < 10; i++) //随机产生50个事件
    //        {
    //            //requisitionType = (RequisitionType)ra.Next(0, 2);
    //            //requisitionType = ra.Next(0, 2);

    //            int m;//m表示随机产生的请求的类型,只能取值0,1,2，取2的概率为1/30
    //            int possibility = ra.Next(0, 10);
    //            if (possibility == 9)
    //                m = ra.Next(0, 3);
    //            else m = ra.Next(0, 2);

    //            if (m==0)
    //            {
    //                updown = ra.Next(0, 2);
    //                //floor = ra.Next(1, MAXFLOOR+1);
    //                floor = ra.Next(0, MAXFLOOR);
    //                eve = new Event(EventType.outsideEvent, floor, updown);
    //            }
    //            else if (m==1)
    //            {
    //                //ID = ra.Next(1, MAXELENUM+1);
    //                //requisitionFloor = ra.Next(1, MAXFLOOR+1);
    //                ID = ra.Next(0, MAXELENUM);
    //                requisitionFloor = ra.Next(0, MAXFLOOR);
    //                eve = new Event(EventType.insideEvent, requisitionFloor, ID);
    //            }
    //            else //m == 2
    //                eve = new Event(EventType.fireEvent);

    //            GConstant.controller.addEvent(eve);
    //        }
    //    }
    //}

    class RandomRequisition : Requisition
    {
        public int MAXELENUM;//最大电梯数目
        public int MAXFLOOR;//最高楼层
        private System.Windows.Threading.Dispatcher dispatcher;
        public RandomRequisition(int MAXFLOOR, int MAXELENUM, System.Windows.Threading.Dispatcher dispatcher)
        {
            this.MAXELENUM = MAXELENUM;
            this.MAXFLOOR = MAXFLOOR;
            this.dispatcher = dispatcher;
        }
        public void createNewRequisition()
        {
            Random ra = new Random();
            int[,] eventArray = new int[10,3];

            //全部的事件都存到数组eventArray里
            for (int i = 0; i < 10; i++) //随机产生50个事件
            {
                //requisitionType = (RequisitionType)ra.Next(0, 2);
                //requisitionType = ra.Next(0, 2);

                int m;//m表示随机产生的请求的类型,只能取值0,1,2，取2的概率为1/30
                int possibility = ra.Next(0, 10);
                if (possibility == 9)
                    m = ra.Next(0, 3);
                else m = ra.Next(0, 2);

                if (m == 0)
                {
                    eventArray[i,2] = ra.Next(0, 2);
                    //floor = ra.Next(1, MAXFLOOR+1);
                    eventArray[i,1] = ra.Next(0, MAXFLOOR);
                    eve = new Event(EventType.outsideEvent, eventArray[i,1], eventArray[i,2]);
                    Thread.Sleep(2 * 1000);
                    subThreadAddEvent(eve);
                }
                else if (m == 1)
                {
                    //ID = ra.Next(1, MAXELENUM+1);
                    //requisitionFloor = ra.Next(1, MAXFLOOR+1);
                    eventArray[i, 2] = ra.Next(0, MAXELENUM);
                    eventArray[i, 1] = ra.Next(0, MAXFLOOR);
                    eve = new Event(EventType.insideEvent, eventArray[i, 1], eventArray[i, 2]);
                    Thread.Sleep(2 * 1000);
                    subThreadAddEvent(eve);
                }
                else //m == 2
                {
                    eve = new Event(EventType.fireEvent);
                    Thread.Sleep(2 * 1000);
                    subThreadAddEvent(eve);
                }
                //GConstant.controller.addEvent(eve);
            }
        }
        public delegate void addEvent(Event even);
        public void addElevatorEvent(Event even)
        {
            GConstant.controller.addEvent(even);
        }
        public void subThreadAddEvent(Event even)
        {
            this.dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new addEvent(addElevatorEvent), even);
        }
    }
}